[PATCH] krb5: use app-layer incomplete support
authorPhilippe Antoine <pantoine@oisf.net>
Wed, 18 Feb 2026 16:19:07 +0000 (17:19 +0100)
committerAndreas Dolp <dev@andreas-dolp.de>
Thu, 23 Apr 2026 05:14:21 +0000 (07:14 +0200)
Ticket: 3540
Ticket: 8305
(cherry picked from commit 8e886a8ecdb5d0b21568be489686a7e0f8136e58)

Origin: upstream, https://github.com/OISF/suricata/commit/4c51a74e2e3a06d352dcac5a720450a392c5c5b2.patch
Bug: https://redmine.openinfosecfoundation.org/issues/8307
Subject: Upstream fix for CVE-2026-31932

Gbp-Pq: Name CVE-2026-31932.patch

rust/src/krb/krb5.rs

index 9ff0ff2157d9fbd364ad57a0d02fdd9804bf9a27..6d9777587a674668e335cf8ed4cc78a7e7cd8a38 100644 (file)
@@ -41,9 +41,7 @@ pub struct KRB5State {
     pub req_id: u8,
 
     pub record_ts: usize,
-    pub defrag_buf_ts: Vec<u8>,
     pub record_tc: usize,
-    pub defrag_buf_tc: Vec<u8>,
 
     /// List of transactions for this session
     transactions: Vec<KRB5Transaction>,
@@ -109,9 +107,7 @@ impl KRB5State {
             state_data: AppLayerStateData::new(),
             req_id: 0,
             record_ts: 0,
-            defrag_buf_ts: Vec::new(),
             record_tc: 0,
-            defrag_buf_tc: Vec::new(),
             transactions: Vec::new(),
             tx_id: 0,
         }
@@ -463,25 +459,9 @@ pub unsafe extern "C" fn rs_krb5_parse_request_tcp(_flow: *const core::Flow,
                                        stream_slice: StreamSlice,
                                        _data: *const std::os::raw::c_void,
                                        ) -> AppLayerResult {
-    let state = cast_pointer!(state,KRB5State);
-    let buf = stream_slice.as_slice();
-
-    let mut v : Vec<u8>;
-    let tcp_buffer = match state.record_ts {
-        0 => buf,
-        _ => {
-            // sanity check to avoid memory exhaustion
-            if state.defrag_buf_ts.len() + buf.len() > 100000 {
-                SCLogDebug!("rs_krb5_parse_request_tcp: TCP buffer exploded {} {}",
-                            state.defrag_buf_ts.len(), buf.len());
-                return AppLayerResult::err();
-            }
-            v = state.defrag_buf_ts.split_off(0);
-            v.extend_from_slice(buf);
-            v.as_slice()
-        }
-    };
-    let mut cur_i = tcp_buffer;
+    let state = cast_pointer!(state, KRB5State);
+    let mut cur_i = stream_slice.as_slice();
+    let start_len = cur_i.len();
     while !cur_i.is_empty() {
         if state.record_ts == 0 {
             match be_u32(cur_i) as IResult<&[u8],u32> {
@@ -490,8 +470,7 @@ pub unsafe extern "C" fn rs_krb5_parse_request_tcp(_flow: *const core::Flow,
                     cur_i = rem;
                 },
                 Err(Err::Incomplete(_)) => {
-                    state.defrag_buf_ts.extend_from_slice(cur_i);
-                    return AppLayerResult::ok();
+                    return AppLayerResult::incomplete((start_len - cur_i.len()) as u32, 4u32);
                 }
                 _ => {
                     SCLogDebug!("rs_krb5_parse_request_tcp: reading record mark failed!");
@@ -507,8 +486,10 @@ pub unsafe extern "C" fn rs_krb5_parse_request_tcp(_flow: *const core::Flow,
             cur_i = &cur_i[state.record_ts..];
         } else {
             // more fragments required
-            state.defrag_buf_ts.extend_from_slice(cur_i);
-            return AppLayerResult::ok();
+            return AppLayerResult::incomplete(
+                (start_len - cur_i.len()) as u32,
+                state.record_ts as u32,
+            );
         }
     }
     AppLayerResult::ok()
@@ -521,25 +502,9 @@ pub unsafe extern "C" fn rs_krb5_parse_response_tcp(_flow: *const core::Flow,
                                        stream_slice: StreamSlice,
                                        _data: *const std::os::raw::c_void,
                                        ) -> AppLayerResult {
-    let state = cast_pointer!(state,KRB5State);
-    let buf = stream_slice.as_slice();
-
-    let mut v : Vec<u8>;
-    let tcp_buffer = match state.record_tc {
-        0 => buf,
-        _ => {
-            // sanity check to avoid memory exhaustion
-            if state.defrag_buf_tc.len() + buf.len() > 100000 {
-                SCLogDebug!("rs_krb5_parse_response_tcp: TCP buffer exploded {} {}",
-                            state.defrag_buf_tc.len(), buf.len());
-                return AppLayerResult::err();
-            }
-            v = state.defrag_buf_tc.split_off(0);
-            v.extend_from_slice(buf);
-            v.as_slice()
-        }
-    };
-    let mut cur_i = tcp_buffer;
+    let state = cast_pointer!(state, KRB5State);
+    let mut cur_i = stream_slice.as_slice();
+    let start_len = cur_i.len();
     while !cur_i.is_empty() {
         if state.record_tc == 0 {
             match be_u32(cur_i) as IResult<&[u8],_> {
@@ -548,8 +513,7 @@ pub unsafe extern "C" fn rs_krb5_parse_response_tcp(_flow: *const core::Flow,
                     cur_i = rem;
                 },
                 Err(Err::Incomplete(_)) => {
-                    state.defrag_buf_tc.extend_from_slice(cur_i);
-                    return AppLayerResult::ok();
+                    return AppLayerResult::incomplete((start_len - cur_i.len()) as u32, 4u32);
                 }
                 _ => {
                     SCLogDebug!("reading record mark failed!");
@@ -565,8 +529,10 @@ pub unsafe extern "C" fn rs_krb5_parse_response_tcp(_flow: *const core::Flow,
             cur_i = &cur_i[state.record_tc..];
         } else {
             // more fragments required
-            state.defrag_buf_tc.extend_from_slice(cur_i);
-            return AppLayerResult::ok();
+            return AppLayerResult::incomplete(
+                (start_len - cur_i.len()) as u32,
+                state.record_tc as u32,
+            );
         }
     }
     AppLayerResult::ok()